home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
program
/
p063b9s.zip
/
UNIT
/
MAILUTIL.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1997-03-02
|
30KB
|
958 lines
UNIT MailUtil;
{╔══════════════════════════════════════════════════════════════════════════╗}
{║ Misc. routines used in a WaZOO session Last changed: 02.03.97 SA ║}
{║ ║}
{║ (C) Copyright 1989-97 by ║}
{║ Dan Wulff, Jens Sandalgaard, Steen Christensen & S¢ren Ager ║}
{║ ║}
{║ This source may not be given to anybody, without the written permission ║}
{║ from The Portal Team. ║}
{╚══════════════════════════════════════════════════════════════════════════╝}
{$I POPDEFS.INC}
INTERFACE
USES Use32, Dos, PopTypes;
VAR
Hello, RemHello : THelloPacket;
HelloByte : ARRAY[1..128] OF Byte ABSOLUTE Hello;
RemHelloByte : ARRAY[1..128] OF Byte ABSOLUTE RemHello;
CONST
ExtFlags : String[5] = 'HDFCI';
DeleteAfter = '-';
ShowDeleteAfter = '^';
TruncAfter = '#';
NothingAfter = '@';
NothingAfterRefuse = '?' ;
VAR
NetProblems : Byte;
FUNCTION ReqOk: Boolean;
FUNCTION IsOurAddress(CONST Adr: TFidoAddress): Boolean;
FUNCTION ProductNames(Num: Word): S30;
FUNCTION NoAll(CONST Adr: TFidoAddress): BOOLEAN;
FUNCTION Address2Sort(CONST Address: TFidoAddress): S8;
PROCEDURE RemapAddress(VAR Adr: TFidoAddress);
FUNCTION CmpAdr(CONST a1, a2: TFidoAddress): Boolean;
FUNCTION GetAdressFromStr(s: String; VAR Address: TFidoAddress) : BOOLEAN;
PROCEDURE FindUnDialable(CONST InAddress: TFidoAddress; VAR NC, BWZ: Word);
PROCEDURE RemoveUnDialable(CONST InAddress: TFidoAddress);
PROCEDURE UpdateUnDialable(CONST InAddress: TFidoAddress; NC, BWZ: Word);
PROCEDURE DisposeNodesIdx;
FUNCTION FindNodeInfo(VAR n: TNodeInfo; CONST Address: TFidoAddress): Boolean;
PROCEDURE PutNodeInfo(VAR n: TNodeInfo);
FUNCTION FindPointNet(VAR n: TNodeInfo; InPointNet: Integer): Boolean;
FUNCTION HoldAreaNameMunge(Zone: Integer; Create: Boolean): PathStr;
FUNCTION HoldAreaPath(CONST Adr: TFidoAddress; Create: Boolean): PathStr;
FUNCTION HoldFileName(CONST Adr: TFidoAddress; Create: Boolean): PathStr;
FUNCTION InventPktName: PathStr;
FUNCTION MakeReqFileName(Net, Node: Integer; NodeStat: TNodeStat): PathStr;
FUNCTION MarkNodeBusy(VAR f: File; CONST Adr: TFidoAddress): Boolean;
PROCEDURE UnMarkNodeBusy(VAR f: File);
PROCEDURE FindSuckerInfo(CONST Adr: TFidoAddress; VAR DRI: TDailyReqInfo);
PROCEDURE WriteSuckerInfo(DRI: TDailyReqInfo);
PROCEDURE GetPktHeadInfo(CONST PH: TPktHeader; Var Orig,Dest: TFidoAddress);
PROCEDURE FillOutPktHeader(CONST Orig,Dest : TFidoAddress; Var PH : TPktHeader);
FUNCTION KludgeLines(CONST Orig,Dest: TFidoAddress):STRING;
IMPLEMENTATION
USES OpString, OpDate, OpRoot,
LogFile, FileUtil, StrUtil, NetFile, Nodelist, SimpDB, MailCfg, Util, Globals;
FUNCTION ReqOk: Boolean;
BEGIN
ReqOk:=NOT isCaller OR ((Cfg.Request.ReqOnUs=ru_Always) OR
((Cfg.Request.ReqOnUs=ru_Cost) AND (FoundInNL) AND (NodelistEntry.Cost<=Cfg.Request.ReqOnUsCost)));
END;
FUNCTION KludgeLines(CONST Orig,Dest: TFidoAddress):STRING;
VAR
s:STRING;
BEGIN
s:=#1'INTL '+Long2Str(Dest.Zone)+':'+Long2Str(Dest.Net)+'/'+Long2Str(Dest.Node)+' '+
Long2Str(Orig.Zone)+':'+Long2Str(Orig.Net)+'/'+Long2Str(Orig.Node);
IF Orig.Point<>0 THEN s:=s+#13#10#1'FMPT '+Long2Str(Orig.Point);
IF Dest.Point<>0 THEN s:=s+#13#10#1'TOPT '+Long2Str(Dest.Point);
s:=s+#13#10#1'PID: PoP '+Ver;
KludgeLines:=s;
END;
PROCEDURE FillOutPktHeader(CONST Orig,Dest : TFidoAddress; Var PH : TPktHeader);
VAR
i : Word;
{$IFDEF OS2}
D, M, Y,
H, Mi, S: Word;
{$ENDIF}
BEGIN
FillChar(ph,Sizeof(TPktHeader),#0);
with ph do
BEGIN
Filler1:=2;
IF FindNodeInfo(NodesRec,Dest) THEN Str2AsciiZ(NodesRec.PktPassWord,PassWord,7);
OrigNode:=Orig.Node;
DestNode:=Dest.Node;
{$IFDEF OS2}
GetDate(Y,M,D,i);
GetTime(H,Mi,S,i);
Year:=Y; Month:=M; Day:=D;
Hour:=H; Min:=Mi; Sec:=S;
{$ELSE}
GetDate(Word(Year),Word(Month),Word(Day),i);
GetTime(Word(Hour),Word(Min),Word(Sec),i);
{$ENDIF}
OrigNet:=Orig.Net;
DestNet:=Dest.Net;
Product:=PopProductCode;
OrigZone:=Orig.Zone;
DestZone:=Dest.Zone;
OrigZone2:=Orig.Zone;
DestZone2:=Dest.Zone;
OrigPoint:=Orig.Point;
DestPoint:=Dest.Point;
Capabil:=1;
CWValHigh:=1;
if Orig.Point <>0 then
BEGIN
AuxNet:=Orig.Net;
OrigNet:=-1;
END;
END;
END;
PROCEDURE GetPktHeadInfo(CONST PH: TPktHeader; Var Orig,Dest : TFidoAddress);
Begin
FillChar(Orig,Sizeof(TFidoAddress),#0);
FillChar(Dest,Sizeof(TFidoAddress),#0);
With PH do
Begin
Orig.Zone:=OrigZone;
Orig.Net:=Orignet;
Orig.node:=orignode;
Dest.Zone:=DestZone;
Dest.Net:=DestNet;
Dest.Node:=destNode;
if (CWValHigh=LO(CapaBil)) AND (CWValLow=HI(CapaBil)) AND
(CWValHigh and 1 <>0) and (CapaBil and 1 <>0) then
BEGIN
if (OrigPoint <> 0) {and (OrigNet=-1)} then
BEGIN
Orig.Net:=AuxNet;
Orig.Point:=OrigPoint;
END;
Dest.Point:=DestPoint;
Orig.Zone:=OrigZone2;
Dest.Zone:=DestZone2;
END;
end;
end;
FUNCTION IsOurAddress(CONST Adr: TFidoAddress): Boolean;
VAR
Found : Boolean;
i : Byte;
BEGIN
Found:=False;
IF Cfg.Addresses[Cfg.MainAdrNum].Point<>0 THEN
BEGIN
IF (Adr.Point=0) AND (Adr.Net=Cfg.PointNet) AND
(Adr.Node=Cfg.Addresses[Cfg.MainAdrNum].Point) THEN Found:=TRUE;
END;
IF NOT Found THEN
FOR i:=1 TO MaxAddresses DO
IF CmpAdr(Adr,Cfg.Addresses[i]) THEN
BEGIN
Found:=True;
Break;
END;
IsOurAddress:=Found;
END;
{----------------------------------------------------------------------------}
{ FidoNet Productcodes }
{----------------------------------------------------------------------------}
FUNCTION ProductNames(Num: Word) : S30;
BEGIN
CASE Num Of
0 : ProductNames:='Fido';
1 : ProductNames:='Rover';
2 : ProductNames:='SEAdog';
3 : ProductNames:='WinDog';
4 : ProductNames:='Slick/150';
5 : ProductNames:='Opus';
6 : ProductNames:='Dutchie';
8 : ProductNames:='Tabby';
10 : ProductNames:='Wolf/68k';
11 : ProductNames:='QMM';
12 : ProductNames:='FrontDoor';
17 : ProductNames:='MailMan';
18 : ProductNames:='OOPS';
19 : ProductNames:='GS-Point';
20 : ProductNames:='BGMail';
25 : ProductNames:='BinkScan';
26 : ProductNames:='D''Bridge';
27 : ProductNames:='BinkleyTerm';
28 : ProductNames:='Yankee';
7,9,
13..16,
21..24,
29,
132: ProductNames:='Dropped ('+Long2Str(Num)+')';
30 : ProductNames:='Daisy';
31 : ProductNames:='Polar Bear';
32 : ProductNames:='The-Box';
33 : ProductNames:='STARgate/2';
34 : ProductNames:='TMail';
35 : ProductNames:='TCOMMail';
36 : ProductNames:='Bananna';
37 : ProductNames:='RBBSMail';
38 : ProductNames:='Apple-Netmail';
39 : ProductNames:='Chameleon';
40 : ProductNames:='Majik Board';
41 : ProductNames:='QMail';
42 : ProductNames:='Point And Click';
43 : ProductNames:='Aurora';
44 : ProductNames:='FourDog';
45 : ProductNames:='MSG-PACK';
46 : ProductNames:='AMAX';
47 : ProductNames:='Domain Communication System';
48 : ProductNames:='LesRobot';
49 : ProductNames:='Rose';
50 : ProductNames:='Paragon';
51 : ProductNames:='BinkleyTerm/oMMM/ST';
52 : ProductNames:='StarNet';
53 : ProductNames:='ZzyZx';
54 : ProductNames:='QuickBBS';
55 : ProductNames:='BOOM';
56 : ProductNames:='PBBS';
57 : ProductNames:='TrapDoor';
58 : ProductNames:='Welmat';
59 : ProductNames:='NetGate';
60 : ProductNames:='Odie';
61 : ProductNames:='Quick Gimme';
62 : ProductNames:='dbLink';
63 : ProductNames:='TosScan';
64 : ProductNames:='Beagle';
65 : ProductNames:='Igor';
66 : ProductNames:='TIMS';
67 : ProductNames:='Isis';
68 : ProductNames:='AirMail';
69 : ProductNames:='XRS';
70 : ProductNames:='Juliet';
71 : ProductNames:='Jabberwocky';
72 : ProductNames:='XST';
73 : ProductNames:='MailStorm';
74 : ProductNames:='BIX-Mail';
75 : ProductNames:='IMAIL';
76 : ProductNames:='FTNGate';
77 : ProductNames:='RealMail';
78 : ProductNames:='Lora-CBIS';
79 : ProductNames:='TDCS';
80 : ProductNames:='InterMail';
81 : ProductNames:='RFD';
82 : ProductNames:='Yuppie!';
83 : ProductNames:='EMMA';
84 : ProductNames:='QBoxMail';
85..86 : ProductNames:='Number '+CHR(Num-33);
87 : ProductNames:='GSBBS';
88 : ProductNames:='Merlin';
89 : ProductNames:='TPCS';
90 : ProductNames:='Raid';
91 : ProductNames:='Outpost';
92 : ProductNames:='Nizze';
93 : ProductNames:='Armadillo';
94 : ProductNames:='Rfmail';
95 : ProductNames:='Msgtoss';
96 : ProductNames:='InfoTex';
97 : ProductNames:='GEcho';
98 : ProductNames:='CDEhost';
99 : ProductNames:='Pktize';
100 : ProductNames:='PC-Rain';
101 : ProductNames:='Truffle';
102 : ProductNames:='Foozle';
103 : ProductNames:='White Pointer';
104 : ProductNames:='GateWorks';
105 : ProductNames:='Portal of Power';
106 : ProductNames:='MacWoof';
107 : ProductNames:='Mosaic';
108 : ProductNames:='TPBEcho';
109 : ProductNames:='HandyMail';
110 : ProductNames:='EchoSmith';
111 : ProductNames:='FileHost';
112 : ProductNames:='SFTS';
113 : ProductNames:='Benjamin';
114 : ProductNames:='RiBBS';
115 : ProductNames:='MP';
116 : ProductNames:='Ping';
117 : ProductNames:='Door2Europe';
118 : ProductNames:='SWIFT';
119 : ProductNames:='WMAIL';
120 : ProductNames:='RATS';
121 : ProductNames:='Harry the Dirty Dog';
122 : ProductNames:='Maximus-CBCS';
123 : ProductNames:='SwifEcho';
124 : ProductNames:='GCChost';
125 : ProductNames:='RPX-Mail';
126 : ProductNames:='Tosser';
127 : ProductNames:='TCL';
128 : ProductNames:='MsgTrack';
129 : ProductNames:='FMail';
130 : ProductNames:='Scantoss';
131 : ProductNames:='Point Manager';
133 : ProductNames:='Simplex';
134 : ProductNames:='UMTP';
135 : ProductNames:='Indaba';
136 : ProductNames:='Echomail Engine';
137 : ProductNames:='DragonMail';
138 : ProductNames:='Prox';
139 : ProductNames:='Tick';
140 : ProductNames:='RA-Echo';
141 : ProductNames:='TrapToss';
142 : ProductNames:='Babel';
143 : ProductNames:='UMS';
144 : ProductNames:='RWMail';
145 : ProductNames:='WildMail';
146 : ProductNames:='AlMAIL';
147 : ProductNames:='XCS';
148 : ProductNames:='Fone-Link';
149 : ProductNames:='Dogfight';
150 : ProductNames:='Ascan';
151 : ProductNames:='FastMail';
152 : ProductNames:='DoorMan';
153 : ProductNames:='PhaedoZap';
154 : ProductNames:='SCREAM';
155 : ProductNames:='MoonMail';
156 : ProductNames:='Backdoor';
157 : ProductNames:='MailLink';
158 : ProductNames:='Mail Manager';
159 : ProductNames:='Black Star';
160 : ProductNames:='Bermuda';
161 : ProductNames:='PT';
162 : ProductNames:='UltiMail';
163 : ProductNames:='GMD';
164 : ProductNames:='FreeMail';
165 : ProductNames:='Meliora';
166 : ProductNames:='Foodo';
167 : ProductNames:='MSBBS';
168 : ProductNames:='Boston BBS';
169 : ProductNames:='XenoMail';
170 : ProductNames:='XenoLink';
171 : ProductNames:='ObjectMatrix';
172 : ProductNames:='Milquetoast';
173 : ProductNames:='PipBase';
174 : ProductNames:='EzyMail';
175 : ProductNames:='FastEcho';
176 : ProductNames:='IOS';
177 : ProductNames:='Communique';
178 : ProductNames:='PointMail';
179 : ProductNames:='Harvey''s Robot';
180 : ProductNames:='2daPoint';
181 : ProductNames:='CommLink';
182 : ProductNames:='fronttoss';
183 : ProductNames:='SysopPoint';
184 : ProductNames:='PTMAIL';
185 : ProductNames:='AECHO';
186 : ProductNames:='DLGMail';
187 : ProductNames:='GatePrep';
188 : ProductNames:='Spoint';
189 : ProductNames:='TurboMail';
190 : ProductNames:='FXMAIL';
191 : ProductNames:='NextBBS';
192 : ProductNames:='EchoToss';
193 : ProductNames:='SilverBox';
194 : ProductNames:='MBMail';
195 : ProductNames:='SkyFreq';
196 : ProductNames:='ProMailer';
197 : ProductNames:='Mega Mail';
198 : ProductNames:='YaBom';
199 : ProductNames:='TachEcho';
200 : ProductNames:='XAP';
201 : ProductNames:='EZMAIL';
202 : ProductNames:='Arc-Binkley';
203 : ProductNames:='Roser';
204 : ProductNames:='UU2';
205 : ProductNames:='NMS';
206 : ProductNames:='BBCSCAN';
207 : ProductNames:='XBBS';
208 : ProductNames:='LoTek Vzrul';
209 : ProductNames:='Private Point';
210 : ProductNames:='NoSnail';
211 : ProductNames:='SmlNet';
212 : ProductNames:='STIR';
213 : ProductNames:='RiscBBS';
214 : ProductNames:='Hercules';
215 : ProductNames:='AMPRGATE';
216 : ProductNames:='BinkEMSI';
217 : ProductNames:='EditMsg';
218 : ProductNames:='Roof';
219 : ProductNames:='QwkPkt';
220 : ProductNames:='MARISCAN';
221 : ProductNames:='NewsFlash';
222 : ProductNames:='Paradise';
223 : ProductNames:='DogMatic-ACB';
224 : ProductNames:='T-Mail';
225 : ProductNames:='JetMail';
226 : ProductNames:='MainDoor';
ELSE ProductNames:='Unknown system ('+HexW(Num)+')';
END;
END;
FUNCTION NoAll(CONST Adr: TFidoAddress): BOOLEAN;
BEGIN
WITH Adr DO
NoAll:=(Zone<>-1) AND (Net<>-1) AND (Node<>-1) AND (Point<>-1);
END;
FUNCTION Address2Sort(CONST Address: TFidoAddress): S8;
BEGIN
WITH Address DO
Address2Sort:=Char(Hi(Zone))+Char(Lo(Zone))+Char(Hi(Net))+Char(Lo(Net))+
Char(Hi(Node))+Char(Lo(Node))+Char(Hi(Point))+Char(Lo(Point));
END;
PROCEDURE RemapAddress(VAR Adr: TFidoAddress);
LABEL
Again;
VAR
OrigPoint : Integer;
PROCEDURE ComputeMaxRequest;
BEGIN
IF FoundInNl OR FoundInNodes THEN
BEGIN
IF (NodelistEntry.Password='') AND (NodesRec.SessionPwd='') THEN
BEGIN
GlobNodeStat:=nsKnown;
END ELSE
BEGIN
GlobNodeStat:=nsPassword;
END;
END ELSE
BEGIN
GlobNodeStat:=nsUnKnown;
END;
MaxReqFiles:=Cfg.Request.Limit[GlobNodeStat,rlPrCall].MaxFiles;
MaxReqBytes:=Cfg.Request.Limit[GlobNodeStat,rlPrCall].MaxBytes;
IF MaxReqBytes=0 THEN MaxReqBytes:=MaxLongInt;
MaxReqTime:=Cfg.Request.Limit[GlobNodeStat,rlPrCall].MaxTime;
IF MaxReqTime=0 THEN MaxReqTime:=MaxTime;
FindSuckerInfo(Adr, DRI);
WITH Cfg.Request.Limit[GlobNodeStat,rlPrDay] DO
BEGIN
IF (MaxFiles>0) AND (MaxReqFiles>MaxFiles-DRI.NumFiles) THEN MaxReqFiles:=MaxFiles-DRI.NumFiles;
IF (MaxBytes>0) AND (MaxReqBytes>MaxBytes-DRI.NumBytes) THEN MaxReqBytes:=MaxBytes-DRI.NumBytes;
IF (MaxTime>0) AND (MaxReqTime>MaxTime-DRI.UsedTime) THEN MaxReqTime:=MaxTime-DRI.UsedTime;
END;
END;
BEGIN
FoundInNl:=False; FoundInNodes:=False;
IF (Cfg.Addresses[Cfg.MainAdrNum].Point=0) AND (Cfg.PointNet<>0) AND (Cfg.UseFakeAddress) THEN
BEGIN
{ Remap egne 4D points til 3D }
IF (Adr.Zone=Cfg.Addresses[Cfg.MainAdrNum].Zone) AND
(Adr.Net=Cfg.Addresses[Cfg.MainAdrNum].Net) AND
(Adr.Node=Cfg.Addresses[Cfg.MainAdrNum].Node) AND
(Adr.Point<>0) THEN
BEGIN
Adr.Net:=Cfg.PointNet;
Adr.Node:=Adr.Point;
Adr.Point:=0;
END;
END ELSE
BEGIN
{ Remap egne 3D points til 4D }
IF (Adr.Zone=Cfg.Addresses[Cfg.MainAdrNum].Zone) AND
(Adr.Net=Cfg.Pointnet) And (Adr.Point=0) THEN
BEGIN
Adr.Point:=Adr.Node;
Adr.Net:=Cfg.Addresses[Cfg.MainAdrNum].Net;
Adr.Node:=Cfg.Addresses[Cfg.MainAdrNum].Node;
END;
END;
OrigPoint:=Adr.Point;
Again:
IF FindNode(Adr,NodelistEntry) THEN
BEGIN
FoundInNl:=True;
END ELSE
BEGIN
IF (Adr.Point=0) And (FindPointNet(NodesRec,Adr.Net)) THEN
BEGIN
Adr.Point:=Adr.Node;
Adr.Net:=NodesRec.Address.Net;
Adr.Node:=NodesRec.Address.Node;
IF FindNode(Adr,NodelistEntry) THEN FoundInNl:=True;
END;
END;
IF FindNodeInfo(NodesRec,Adr) THEN
FoundInNodes:=True
ELSE
IF NOT FoundInNL AND (Adr.Point<>0) THEN
BEGIN
Adr.Point:=0;
GOTO Again;
END;
ComputeMaxRequest;
Adr.Point:=OrigPoint;
END;
FUNCTION CmpAdr(CONST a1, a2: TFidoAddress): Boolean;
BEGIN
CmpAdr:=(a1.Zone=a2.Zone) And (a1.Net=a2.Net) And (a1.Node=a2.Node) And (a1.Point=a2.Point);
END;
FUNCTION GetAdressFromStr(s: String; VAR Address: TFidoAddress): BOOLEAN;
VAR
test,i:INTEGER;
BEGIN
GetAdressFromStr:=FALSE;
FILLCHAR(Address,SizeOf(TFidoAddress),0);
i:=POS('@',s);
IF i>0 THEN s:=COPY(s,1,i-1);
Replace(s,' ','',0);
i:=POS(':',s);
IF i=0 THEN Address.Zone:=Cfg.Addresses[Cfg.MainAdrNum].Zone ELSE
BEGIN
VAL(COPY(s,1,i-1),Address.Zone,test);
IF test>0 THEN EXIT;
DELETE(s,1,i);
END;
i:=POS('/',s);
IF i=0 THEN Address.Net:=Cfg.Addresses[Cfg.MainAdrNum].Net ELSE
BEGIN
VAL(COPY(s,1,i-1),Address.Net,test);
IF test>0 THEN EXIT;
DELETE(s,1,i);
END;
i:=POS('.',s);
IF i=0 THEN
BEGIN
VAL(s,Address.Node,test);
s:='';
END ELSE
BEGIN
VAL(COPY(s,1,i-1),Address.Node,Test);
DELETE(s,1,i);
END;
IF test>0 THEN EXIT;
VAL(s,Address.Point,Test);
IF Test<>0 THEN Address.point:=0;
GetAdressFromStr:=TRUE;
END;
{--- PORTAL.UDF managment routines ------------------------------------------}
PROCEDURE FindUnDialable(CONST InAddress: TFidoAddress; VAR NC, BWZ : Word);
VAR
Found : Boolean;
UnDialable : PSimpDB;
UnDialableRec : TUndialable;
BEGIN
Found:=False;
New(Undialable, Open(StartPath+PoPUndialFileName, SizeOf(TUndialable), False));
IF Undialable<>Nil THEN
BEGIN
WHILE NOT Found AND UnDialable^.NextRec(UnDialableRec, NoKeep) DO
BEGIN
Found:=CmpAdr(InAddress,UnDialableRec.Address);
END;
Dispose(UnDialable, Close);
END;
IF Found THEN
BEGIN
NC:=UnDialableRec.NoConnect;
BWZ:=UnDialableRec.BadWaZOO;
END ELSE
BEGIN
NC:=0;
BWZ:=0;
END;
END;
PROCEDURE RemoveUnDialable(CONST InAddress: TFidoAddress);
VAR
Found : Boolean;
UnDial : PSimpDB;
UnDialRec : TUndialable;
BEGIN
New(Undial, Open(StartPath+PoPUndialFileName, SizeOf(TUndialable), False));
IF Undial<>Nil THEN
BEGIN
Found:=False;
WHILE NOT Found AND UnDial^.NextRec(UndialRec, Keep) DO
BEGIN
IF CmpAdr(InAddress, UnDialRec.Address) THEN
BEGIN
UnDial^.DelRec(UndialRec, UnDial^.FilePos-1);
Found:=True
END ELSE
UnDial^.Unlock(UnDial^.FilePos-1);
END;
Dispose(UnDial, Close);
END;
END;
PROCEDURE UpdateUnDialable;
VAR
Found : Boolean;
UnDial : PSimpDB;
UnDialRec : TUndialable;
BEGIN
New(Undial, Open(StartPath+PoPUndialFileName, SizeOf(TUndialable), True));
IF Undial<>NIL THEN
BEGIN
Found:=False;
WHILE NOT Found AND Undial^.NextRec(UndialRec, Keep) DO
BEGIN
IF CmpAdr(InAddress,UnDialRec.Address) THEN
Found:=True
ELSE
UnDial^.Unlock(UnDial^.FilePos-1);
END;
IF NOT Found THEN FillChar(UnDialRec, SizeOf(UnDialRec), 0);
WITH UnDialRec DO
BEGIN
Address:=InAddress;
NoConnect:=NoConnect+NC;
BadWaZOO:=BadWaZOO+BWZ;
END;
IF Found THEN
Undial^.PutRec(UnDialRec, UnDial^.FilePos-1)
ELSE
Undial^.AddRec(UnDialRec);
Dispose(UnDial, Close);
END ELSE
AddLog('!', 'Not enough memory to open: '+PoPUndialFileName);
END;
{=== PORTAL.NOD managment routines ===}
TYPE
TNodesIdx = RECORD
NumRecs : Word;
FileTime : LongInt;
RecInfo : ARRAY[0..5000] OF RECORD
Adr : TFidoAddress;
PointNet : Integer;
END;
END;
PROCEDURE DisposeNodesIdx;
BEGIN
IF NodesIdx<>NIL THEN
FreeMemCheck(NodesIdx, 6+TNodesIdx(NodesIdx^).NumRecs*10{SizeOf(TNodesIdx.RecInfo[0])});
END;
PROCEDURE CheckForReReadNodes(Forced: Boolean);
VAR
f : TNetFile;
n : TNodeInfo;
ReadIt : Boolean;
Sr : SearchRec;
BEGIN
ReadIt:=(NodesIdx=NIL) OR Forced;
IF NOT ReadIt THEN
BEGIN
FindFirst(StartPath+PoPNodesFileName, Archive, Sr);
FindClose(Sr);
ReadIt:=Sr.Time<>TNodesIdx(NodesIdx^).FileTime;
END;
IF ReadIt THEN
BEGIN
DisposeNodesIdx;
IF f.Open(StartPath+PoPNodesFileName, SizeOf(TNodeInfo), False) THEN
BEGIN
IF f.FileSize>0 THEN
BEGIN
{
addlog('*','Reading nodes...');
}
GetMem(NodesIdx, 6+f.FileSize*10{SizeOf(TNodesIdx.RecInfo[0])});
TNodesIdx(NodesIdx^).NumRecs:=f.FileSize;
GetFTime(f, TNodesIdx(NodesIdx^).FileTime);
WHILE NOT f.EoF DO
BEGIN
f.Read(n, NoKeep, Wait);
IF (f.IOResult=0) THEN
BEGIN
TNodesIdx(NodesIdx^).RecInfo[f.FilePos-1].Adr:=n.Address;
TNodesIdx(NodesIdx^).RecInfo[f.FilePos-1].PointNet:=n.PointNet;
END;
END;
END;
f.Close;
END;
END;
END;
FUNCTION FindNodeInIdx(VAR Num: Word; CONST Adr: TFidoAddress): Boolean;
BEGIN
IF NodesIdx<>NIL THEN
BEGIN
Num:=0;
WHILE (Num<TNodesIdx(NodesIdx^).NumRecs) AND NOT CmpAdr(Adr, TNodesIdx(NodesIdx^).RecInfo[Num].Adr) DO
Inc(Num);
FindNodeInIdx:=(Num<TNodesIdx(NodesIdx^).NumRecs);
END ELSE
FindNodeInIdx:=False;
END;
FUNCTION FindPointNetInIdx(VAR Num: Word; PNet: Integer): Boolean;
BEGIN
IF NodesIdx<>NIL THEN
BEGIN
Num:=0;
WHILE (Num<TNodesIdx(NodesIdx^).NumRecs) AND (PNet<>TNodesIdx(NodesIdx^).RecInfo[Num].PointNet) DO
Inc(Num);
FindPointNetInIdx:=(Num<TNodesIdx(NodesIdx^).NumRecs);
END ELSE
FindPointNetInIdx:=False;
END;
FUNCTION FindNodeInfo(VAR n: TNodeInfo; CONST Address: TFidoAddress): Boolean;
LABEL
TryAgain;
VAR
f : TNetFile;
Num : Word;
BEGIN
CheckForReReadNodes(False);
TryAgain:
IF NOT FindNodeInIdx(Num, Address) THEN
BEGIN
_NodesInit(n);
{ FillChar(n, SizeOf(n), 0);}
END ELSE
BEGIN
IF f.Open(StartPath+PoPNodesFileName, SizeOf(TNodeInfo), False) THEN
BEGIN
f.GetRec(n, Num, NoKeep, Wait);
f.Close;
IF NOT CmpAdr(n.Address, Address) THEN { Something has invalidated the index - reread it! }
BEGIN
CheckForReReadNodes(True);
GOTO TryAgain;
END;
END;
END;
FindNodeInfo:=(NodesIdx<>NIL) AND (Num<TNodesIdx(NodesIdx^).NumRecs);
END;
PROCEDURE PutNodeInfo(VAR n: TNodeInfo);
LABEL
TryAgain;
VAR
f : TNetFile;
Found : Boolean;
o : TNodeInfo;
Num : Word;
BEGIN
CheckForReReadNodes(False);
TryAgain:
Found:=FindNodeInIdx(Num, n.Address);
f.Open(StartPath+PoPNodesFileName, SizeOf(TNodeInfo), True) ;
IF Found THEN
BEGIN
f.GetRec(o, Num, Keep, Wait);
IF NOT CmpAdr(o.Address, n.Address) THEN { Something has invalidated the index - reread it! }
BEGIN
f.Unlock(f.FilePos-1);
f.Close;
CheckForReReadNodes(True);
GOTO TryAgain;
END;
END ELSE
f.Seek(f.FileSize);
f.PutRec(n, Num);
f.Close;
END;
FUNCTION FindPointNet(VAR n: TNodeInfo; InPointNet: Integer): Boolean;
LABEL
TryAgain;
VAR
f : TNetFile;
Found : Boolean;
Num : Word;
BEGIN
CheckForReReadNodes(False);
Found:=False;
IF InPointNet<>0 THEN
BEGIN
TryAgain:
Found:=FindPointNetInIdx(Num, InPointNet);
IF Found THEN
BEGIN
f.Open(StartPath+PoPNodesFileName, SizeOf(TNodeInfo), False);
f.GetRec(n, Num, NoKeep, Wait);
f.Close;
IF (InPointNet<>n.PointNet) THEN
BEGIN
CheckForReReadNodes(True);
GOTO TryAgain;
END;
END;
END;
IF NOT Found THEN _NodesInit(n);
FindPointNet:=Found;
END;
{--- Outbound path managment ------------------------------------------------}
FUNCTION HoldAreaNameMunge(Zone: Integer; Create: Boolean) : PathStr;
VAR
s : PathStr;
BEGIN
s:=ReplaceEnv(Cfg.Outbound);
IF Zone<>Cfg.Addresses[Cfg.MainAdrNum].Zone THEN s:=s+'.'+Copy(HexW(Zone),2,3);
IF NOT ChkDir(s) AND Create THEN MakeFullDir(s);
HoldAreaNameMunge:=AddBackSlash(s);
END;
FUNCTION HoldAreaPath(CONST Adr: TFidoAddress; Create: Boolean): PathStr;
VAR
s : PathStr;
BEGIN
s:=HoldAreaNameMunge(Adr.Zone,Create);
IF Adr.Point<>0 THEN
BEGIN
s:=s+Address(Adr.Net,Adr.Node)+'.PNT';
IF NOT ChkDir(s) AND Create THEN MakeFullDir(s);
END;
HoldAreaPath:=AddBackSlash(s);
END;
FUNCTION HoldFileName(CONST Adr: TFidoAddress; Create: Boolean): PathStr;
VAR
s: PathStr;
BEGIN
s:=HoldAreaPath(Adr,Create);
IF Adr.Point<>0 THEN
BEGIN
s:=s+Address(0,Adr.Point);
END ELSE
BEGIN
s:=s+Address(Adr.Net,Adr.Node);
END;
HoldFileName:=s+'.';
END;
FUNCTION InventPktName: PathStr;
VAR
Hour, Min, Sec, Sec100: Word;
BEGIN
GetTime(Hour, Min, Sec, Sec100);
InventPktName:=Copy(HexW(Hour),3,2)+Copy(HexW(Min),3,2)+
Copy(HexW(Sec),3,2)+Copy(HexW(Sec100),3,2)+'.PKT';
END;
FUNCTION MakeReqFileName(Net, Node: Integer; NodeStat: TNodeStat): PathStr;
BEGIN
MakeReqFileName:=ReplaceEnv(Cfg.Inbound[NodeStat])+HexW(Net)+HexW(Node)+'.R'+HexB(Cfg.TaskNumber);
END;
FUNCTION MarkNodeBusy(VAR f: File; CONST Adr: TFidoAddress): Boolean;
VAR
Sr : SearchRec;
FName : PathStr;
IORes : Integer;
BEGIN
IF Cfg.TaskNumber>0 THEN
BEGIN
IORes:=IOResult;
IF IORes<>0 THEN AddLog('!','I/O error before creating busy flag ('+Long2Str(IORes)+')');
FName:=HoldFileName(Adr, False)+'BSY';
FindFirst(FName, AnyFile, Sr);
IF DOSError=18 THEN { No more files }
BEGIN
Assign(f, FName);
ReWrite(f);
MarkNodeBusy:=(IOResult=0);
END ELSE
BEGIN
MarkNodeBusy:=(DOSError=3); { Path not found }
END;
FindClose(Sr);
END ELSE
MarkNodeBusy:=True;
END;
PROCEDURE UnMarkNodeBusy(VAR f: File);
VAR
i : Integer;
BEGIN
IF Cfg.TaskNumber>0 THEN
BEGIN
i:=IOResult;
IF i<>0 THEN AddLog('!','I/O error before removing busy flag ('+Long2Str(i)+')');
Close(f);
i:=IOResult;
IF i=0 THEN
BEGIN
Erase(f);
i:=IOResult;
END;
{ 103 pga. at ikke existerende zone outbounds ikke oprettes }
IF NOT (i IN [0, 103]) THEN AddLog('!','Error removing busy flag ('+Long2Str(i)+')');
END;
END;
PROCEDURE FindSuckerInfo(CONST Adr: TFidoAddress; VAR DRI: TDailyReqInfo);
VAR
f : TNetFile;
Found : Boolean;
BEGIN
Found:=False;
IF f.Open(StartPath+PoPDailyReqInfoFileName, SizeOf(TDailyReqInfo), False) THEN
BEGIN
REPEAT
f.Read(DRI, NoKeep, Wait);
Found:=CmpAdr(Adr, DRI.Address);
UNTIL Found OR f.EoF;
f.Close;
END;
IF NOT Found THEN
BEGIN
FillChar(DRI, SizeOf(DRI), 0);
DRI.Address:=Adr;
END;
END;
PROCEDURE WriteSuckerInfo(DRI: TDailyReqInfo);
VAR
TmpDRI : TDailyReqInfo;
f : TNetFile;
Found : Boolean;
BEGIN
IF f.Open(StartPath+PoPDailyReqInfoFileName, SizeOf(TDailyReqInfo), True) THEN
BEGIN
Found:=False;
WHILE NOT f.EoF AND NOT Found DO
BEGIN
f.Read(TmpDRI, Keep, Wait);
IF CmpAdr(TmpDRI.Address, DRI.Address) THEN Found:=True ELSE f.UnLock(f.FilePos-1);
END;
IF Found THEN f.Seek(f.FilePos-1);
f.Write(DRI);
f.Close;
END;
END;
END.